#include "viml/debugger_cli.h"
#include <iostream>
#include <sstream>
#include <algorithm>
#include <cctype>

namespace viml {

// ========== 辅助方法实现 ========== //

void DebuggerCLI::register_command(const DebugCommand& command) {
    command_registry[command.name] = command;
}

void DebuggerCLI::register_alias(const std::string& alias, const std::string& command) {
    command_aliases[alias] = command;
}

int DebuggerCLI::parse_line_number(const std::string& line_str) {
    try {
        return std::stoi(line_str);
    } catch (...) {
        return -1;
    }
}

std::string DebuggerCLI::parse_condition_expression(const std::vector<std::string>& args, size_t start_index) {
    std::string condition;
    for (size_t i = start_index; i < args.size(); ++i) {
        if (i > start_index) condition += " ";
        condition += args[i];
    }
    return condition;
}

void DebuggerCLI::execute_command(const DebugCommand& command) {
    // 处理所有基本调试命令
    switch (command.type) {
        case DebugCommandType::HELP:
            cmd_help(command.args);
            break;
        case DebugCommandType::QUIT:
            cmd_quit(command.args);
            break;
        case DebugCommandType::CONTINUE:
            cmd_continue(command.args);
            break;
        case DebugCommandType::STEP:
            cmd_step(command.args);
            break;
        case DebugCommandType::STEP_INTO:
            cmd_step_into(command.args);
            break;
        case DebugCommandType::STEP_OVER:
            cmd_step_over(command.args);
            break;
        case DebugCommandType::STEP_OUT:
            cmd_step_out(command.args);
            break;
        case DebugCommandType::BREAKPOINT:
            cmd_breakpoint(command.args);
            break;
        case DebugCommandType::BREAK:
            cmd_break(command.args);
            break;
        case DebugCommandType::CLEAR:
            cmd_clear(command.args);
            break;
        case DebugCommandType::DELETE:
            cmd_delete(command.args);
            break;
        case DebugCommandType::LIST:
            cmd_list(command.args);
            break;
        case DebugCommandType::INFO:
            cmd_info(command.args);
            break;
        case DebugCommandType::BACKTRACE:
            cmd_backtrace(command.args);
            break;
        case DebugCommandType::WHERE:
            cmd_where(command.args);
            break;
        case DebugCommandType::PRINT:
            cmd_print(command.args);
            break;
        case DebugCommandType::LOCALS:
            cmd_locals(command.args);
            break;
        case DebugCommandType::GLOBALS:
            cmd_globals(command.args);
            break;
        case DebugCommandType::FRAME:
            cmd_frame(command.args);
            break;
        case DebugCommandType::UP:
            cmd_up(command.args);
            break;
        case DebugCommandType::DOWN:
            cmd_down(command.args);
            break;
        case DebugCommandType::DISASSEMBLE:
            cmd_disassemble(command.args);
            break;
        case DebugCommandType::RUN:
            cmd_run(command.args);
            break;
        case DebugCommandType::FINISH:
            cmd_finish(command.args);
            break;
        case DebugCommandType::CONDITION:
            cmd_condition(command.args);
            break;
        case DebugCommandType::IGNORE:
            cmd_ignore(command.args);
            break;
        case DebugCommandType::ENABLE:
            cmd_enable(command.args);
            break;
        case DebugCommandType::DISABLE:
            cmd_disable(command.args);
            break;
        default:
            show_error("未知命令: " + command.name);
            break;
    }
}

// ========== 命令初始化 ========== //

void DebuggerCLI::initialize_commands() {
    register_command({
        DebugCommandType::HELP, "help", {"h", "?"},
        "显示帮助信息"
    });

    register_command({
        DebugCommandType::QUIT, "quit", {"q", "exit"},
        "退出调试器"
    });

    register_command({
        DebugCommandType::CONTINUE, "continue", {"c", "run"},
        "继续执行程序"
    });

    register_command({
        DebugCommandType::STEP, "step", {"n", "next"},
        "单步执行下一条指令"
    });

    register_command({
        DebugCommandType::STEP_INTO, "stepinto", {"si"},
        "单步进入函数"
    });

    register_command({
        DebugCommandType::STEP_OVER, "stepover", {"so"},
        "单步跳过函数"
    });

    register_command({
        DebugCommandType::STEP_OUT, "stepout", {"finish"},
        "单步退出当前函数"
    });

    register_command({
        DebugCommandType::BREAKPOINT, "breakpoint", {"bp"},
        "显示断点信息"
    });

    register_command({
        DebugCommandType::BREAK, "break", {"b"},
        "设置断点"
    });

    register_command({
        DebugCommandType::CLEAR, "clear", {"delete"},
        "清除指定断点"
    });

    register_command({
        DebugCommandType::DELETE, "delete", {"del", "remove"},
        "删除指定断点"
    });

    register_command({
        DebugCommandType::LIST, "list", {"info", "show"},
        "列出断点"
    });

    register_command({
        DebugCommandType::INFO, "info", {},
        "显示调试信息"
    });

    register_command({
        DebugCommandType::BACKTRACE, "backtrace", {"bt"},
        "显示调用栈"
    });

    register_command({
        DebugCommandType::WHERE, "where", {},
        "显示当前位置"
    });

    register_command({
        DebugCommandType::PRINT, "print", {"p"},
        "打印表达式值"
    });

    register_command({
        DebugCommandType::LOCALS, "locals", {"l"},
        "显示局部变量"
    });

    register_command({
        DebugCommandType::GLOBALS, "globals", {"g"},
        "显示全局变量"
    });

    register_command({
        DebugCommandType::FRAME, "frame", {"f"},
        "选择调用栈帧"
    });

    register_command({
        DebugCommandType::UP, "up", {"u"},
        "向上移动栈帧"
    });

    register_command({
        DebugCommandType::DOWN, "down", {"d"},
        "向下移动栈帧"
    });

    register_command({
        DebugCommandType::DISASSEMBLE, "disassemble", {"x", "disasm"},
        "显示反汇编"
    });

    register_command({
        DebugCommandType::RUN, "run", {"start"},
        "运行程序"
    });

    register_command({
        DebugCommandType::FINISH, "finish", {"return"},
        "完成当前函数"
    });

    // 设置命令别名
    register_alias("q", "quit");
    register_alias("h", "help");
    register_alias("n", "step");
    register_alias("c", "continue");
    register_alias("si", "stepinto");
    register_alias("so", "stepover");
    register_alias("bt", "backtrace");
    register_alias("l", "locals");
    register_alias("g", "globals");
    register_alias("p", "print");
}

// ========== 命令解析 ========== //

DebugCommand DebuggerCLI::parse_command(const std::string& input) {
    if (input.empty()) {
        return DebugCommand(DebugCommandType::UNKNOWN);
    }

    std::istringstream iss(input);
    std::string command_name;
    iss >> command_name;

    std::string command_lower = command_name;
    std::transform(command_lower.begin(), command_lower.end(), command_lower.begin(), ::tolower);

    // 查找匹配的命令
    for (const auto& pair : command_registry) {
        const DebugCommand& cmd = pair.second;

        // 检查主命令名
        if (cmd.name == command_lower) {
            // 解析剩余参数
            std::vector<std::string> args;
            std::string arg;
            while (iss >> arg) {
                args.push_back(arg);
            }
            return DebugCommand(cmd.type, command_name, args, cmd.help_text);
        }

        // 检查别名
        for (const auto& alias_pair : command_aliases) {
            if (alias_pair.first == command_lower && alias_pair.second == cmd.name) {
                std::vector<std::string> args;
                std::string arg;
                while (iss >> arg) {
                    args.push_back(arg);
                }
                return DebugCommand(cmd.type, command_name, args, cmd.help_text);
            }
        }
    }

    return DebugCommand(DebugCommandType::UNKNOWN, command_name);
}

bool DebuggerCLI::validate_command(const DebugCommand& command) {
    if (command.type == DebugCommandType::UNKNOWN) {
        return false;
    }
    return true;
}

// ========== 命令执行器 ========== //

void DebuggerCLI::cmd_help(const std::vector<std::string>& args) {
    if (!display) {
        return;
    }

    if (args.empty()) {
        display->show_help();
    } else {
        for (const auto& arg : args) {
            display->show_help(arg);
        }
    }
}

void DebuggerCLI::cmd_quit(const std::vector<std::string>& args) {
    (void)args; // 忽略参数
    should_quit = true;
    if (display) {
        display->show_goodbye();
    }
}

void DebuggerCLI::cmd_continue(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!debugger || !vm) {
        show_error("调试器或虚拟机未初始化");
        return;
    }

    show_info("继续执行程序...");

    // 设置程序执行标志，vimlc_debug将在CLI退出后执行程序
    set_should_execute_program(true);

    // 退出CLI调试器，让vimlc_debug执行实际程序
    should_quit = true;

    show_info("继续执行程序，即将退出调试模式...");
}

void DebuggerCLI::cmd_step(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!debugger || !vm) {
        show_error("调试器或虚拟机未初始化");
        return;
    }

    show_info("单步执行...");

    // 启用单步模式
    debugger->step_into();

    // 设置程序执行标志，表示要进行单步执行
    set_should_execute_program(true);
    set_should_step_execute(true);

    // 设置单步执行标志，程序执行后会立即返回到调试器
    // 这需要与vimlc_debug集成来真正实现单步执行
    show_info("执行一条指令后暂停...");

    // 退出CLI，让vimlc_debug执行单步调试
    should_quit = true;
}

void DebuggerCLI::cmd_step_into(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!debugger) {
        return;
    }

    debugger->step_into();
    pause_debugger();
}

void DebuggerCLI::cmd_step_over(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!debugger) {
        return;
    }

    debugger->step_over();
    pause_debugger();
}

void DebuggerCLI::cmd_step_out(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!debugger) {
        return;
    }

    debugger->step_out();
    pause_debugger();
}

void DebuggerCLI::cmd_breakpoint(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!display) {
        return;
    }

    display->show_breakpoints();
}

void DebuggerCLI::cmd_break(const std::vector<std::string>& args) {
    if (!debugger) {
        return;
    }

    if (args.empty()) {
        return;
    }

    int line = std::stoi(args[0]);
    if (line <= 0) {
        show_error("无效的行号: " + args[0]);
        return;
    }

    std::string condition = "";
    if (args.size() > 1) {
        condition = parse_condition_expression(args, 1);
    }

    size_t bp_id = debugger->set_breakpoint(line, condition);
    show_info("设置断点 " + std::to_string(bp_id) + " 在第 " + std::to_string(line) + " 行");

    if (display) {
        display->show_breakpoints();
    }
}

void DebuggerCLI::cmd_clear(const std::vector<std::string>& args) {
    cmd_delete(args);
}

void DebuggerCLI::cmd_delete(const std::vector<std::string>& args) {
    if (!debugger) {
        return;
    }

    if (args.empty()) {
        return;
    }

    if (args[0] == "all" || args[0] == "*") {
        debugger->clear_all_breakpoints();
        show_info("已清除所有断点");
    } else {
        // 尝试解析为断点ID
        try {
            size_t bp_id = std::stoull(args[0]);
            if (debugger->remove_breakpoint(bp_id)) {
                show_info("已删除断点 " + std::to_string(bp_id));
            } else {
                // return;
            }
        } catch (const std::exception& e) {
            show_error("无效的断点ID: " + args[0]);
        }
    }

    if (display) {
        display->show_breakpoints();
    }
}

void DebuggerCLI::cmd_list(const std::vector<std::string>& args) {
    cmd_info(args);
}

void DebuggerCLI::cmd_info(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!display) {
        return;
    }

    display->show_current_location();
    display->show_breakpoints();
    display->show_call_stack();
    display->show_source_context();
}

void DebuggerCLI::show_info(const std::string& info) {
    std::cout << info << std::endl;
}

void DebuggerCLI::show_error(const std::string& error) {
    std::cerr << "错误: " << error << std::endl;
}

void DebuggerCLI::cmd_backtrace(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!display) {
        return;
    }

    display->show_call_stack();
    display->show_current_location();
}

void DebuggerCLI::cmd_where(const std::vector<std::string>& args) {
    cmd_backtrace(args);
}

void DebuggerCLI::cmd_print(const std::vector<std::string>& args) {
    if (args.empty()) {
        return;
    }

    // 简化实现：显示变量值
    std::string var_name = args[0];
    auto variables = debugger->get_all_variables();

    auto it = variables.find(var_name);
    if (it != variables.end()) {
        std::cout << var_name << " = " << display->format_value(it->second) << std::endl;
    } else {
        show_error("未找到变量: " + var_name);
    }
}

void DebuggerCLI::cmd_locals(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!display) {
        return;
    }

    display->show_locals();
}

void DebuggerCLI::cmd_globals(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!display) {
        return;
    }

    display->show_globals();
}

void DebuggerCLI::cmd_frame(const std::vector<std::string>& args) {
    if (args.empty()) {
        return;
    }

    try {
        size_t frame_num = std::stoull(args[0]);
        std::string info = display->format_frame_info(frame_num);
        show_info(info);
    } catch (const std::exception& e) {
        show_error("无效的栈帧编号: " + args[0]);
    }
}

void DebuggerCLI::cmd_up(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    // 这里需要实现栈帧向上移动的逻辑
    show_info("向上移动栈帧 (待实现)");
}

void DebuggerCLI::cmd_down(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    // 这里需要实现栈帧向下移动的逻辑
    show_info("向下移动栈帧 (待实现)");
}

void DebuggerCLI::cmd_disassemble(const std::vector<std::string>& args) {
    int start_pc = 0;
    int count = 10;

    if (!args.empty()) {
        try {
            start_pc = std::stoi(args[0]);
        } catch (const std::exception&) {
            // 忽略无效参数
        }

        if (args.size() > 1) {
            try {
                count = std::stoi(args[1]);
            } catch (const std::exception&) {
                // 使用默认值
            }
        }
    }

    if (display) {
        display->show_disassembly(start_pc, count);
    }
}

void DebuggerCLI::cmd_run(const std::vector<std::string>& args) {
    (void)args; // 忽略参数

    if (!debugger || !vm) {
        show_error("调试器或虚拟机未初始化");
        return;
    }

    show_info("开始执行程序...");

    // 启动调试器
    start_debugger();
    is_running = true;

    // 设置程序执行标志，vimlc_debug将在CLI退出后执行程序
    set_should_execute_program(true);

    // 退出CLI调试器，让vimlc_debug执行实际程序
    should_quit = true;

    show_info("准备执行程序，即将退出调试模式...");
}

void DebuggerCLI::cmd_finish(const std::vector<std::string>& args) {
    cmd_step_out(args);
}

void DebuggerCLI::cmd_condition(const std::vector<std::string>& args) {
    if (args.empty()) {
        return;
    }

    show_info("条件断点功能待实现");
}

void DebuggerCLI::cmd_ignore(const std::vector<std::string>& args) {
    (void)args; // 忽略参数
    show_info("断点忽略功能待实现");
}

void DebuggerCLI::cmd_enable(const std::vector<std::string>& args) {
    if (args.empty()) {
        return;
    }

    try {
        size_t bp_id = std::stoull(args[0]);
        if (debugger->enable_breakpoint(bp_id, true)) {
            show_info("启用断点 " + std::to_string(bp_id));
        } else {
            // return;
        }
    } catch (const std::exception& e) {
        show_error("无效的断点ID: " + args[0]);
    }
}

void DebuggerCLI::cmd_disable(const std::vector<std::string>& args) {
    if (args.empty()) {
        return;
    }

    try {
        size_t bp_id = std::stoull(args[0]);
        if (debugger->enable_breakpoint(bp_id, false)) {
            show_info("禁用断点 " + std::to_string(bp_id));
        } else {
            // return;
        }
    } catch (const std::exception& e) {
        show_error("无效的断点ID: " + args[0]);
    }
}

// ========== 调试状态管理 ========== //

void DebuggerCLI::start_debugger() {
    if (debugger) {
        debugger->start();
    }
    is_running = true;
    should_quit = false;
}

void DebuggerCLI::stop_debugger() {
    is_running = false;
}

void DebuggerCLI::pause_debugger() {
    if (debugger) {
        debugger->pause();
    }
    is_running = false;
}

void DebuggerCLI::resume_debugger() {
    if (debugger) {
        debugger->resume();
    }
    is_running = true;
}

void DebuggerCLI::update_debugger_state() {
    if (!debugger) return;

    if (debugger->is_paused()) {
        is_running = false;
        if (display) {
            display->show_current_location();
            display->show_source_context();
        }
    }
}

// ========== 用户交互 ========== //

std::string DebuggerCLI::read_command_line() {
    std::cout << "(dbg) ";
    std::string line;
    std::getline(std::cin, line);
    return line;
}

std::vector<std::string> DebuggerCLI::complete_command(const std::string& partial) {
    if (!completer) {
        return {};
    }

    return completer->complete(partial, partial.length());
}

void DebuggerCLI::handle_command_completion() {
    // 简化的命令补全实现
    // 实际实现需要更复杂的逻辑
}

// ========== 构造函数和主要接口 ========== //

DebuggerCLI::DebuggerCLI(std::shared_ptr<VM> virtual_machine,
                       std::shared_ptr<Debugger> dbg,
                       std::shared_ptr<DebugInfo> info)
    : vm(virtual_machine), debugger(dbg), debug_info(info)
    , is_running(false), should_quit(false) {

    display = std::make_unique<DebugDisplay>(debugger, debug_info);
    history = std::make_unique<DebugHistory>();
    completer = std::make_unique<CommandCompleter>();

    initialize_commands();
}


bool DebuggerCLI::load_file(const std::string& filename) {
    if (filename.empty()) {
        // return;
        return false;
    }

    current_file = filename;

    // 这里应该加载文件并设置断点等
    // 简化实现
    show_info("已加载文件: " + filename);
    return true;
}

int DebuggerCLI::run_interactive() {
    if (!display) {
        // return;
        return -1;
    }

    display->show_welcome();

    while (!should_quit) {
        update_debugger_state();

        if (!is_running && !should_quit) {
            // 只在暂停状态下接受命令
            std::string input = read_command_line();
            if (!input.empty()) {
                history->add(input);

                DebugCommand cmd = parse_command(input);
                if (validate_command(cmd)) {
                    execute_command(cmd);
                } else {
                    show_error("未知命令: " + cmd.name);
                }
            }
        }
    }

    return 0;
}

int DebuggerCLI::run_single_command(const std::string& command) {
    if (!display) {
        // return;
        return -1;
    }

    DebugCommand cmd = parse_command(command);
    if (validate_command(cmd)) {
        execute_command(cmd);
    } else {
        show_error("未知命令: " + cmd.name);
    }

    return 0;
}

void DebuggerCLI::set_debugger(std::shared_ptr<Debugger> dbg) {
    debugger = dbg;
}

void DebuggerCLI::set_debug_info(std::shared_ptr<DebugInfo> info) {
    debug_info = info;
}

void DebuggerCLI::configure_display(bool show_instructions,
                               bool show_registers,
                               bool show_stack_trace,
                               int source_context) {
    if (display) {
        display->set_show_instructions(show_instructions);
        display->set_show_registers(show_registers);
        display->set_show_stack_trace(show_stack_trace);
        display->set_source_context_lines(source_context);
    }
}

// ========== 工厂函数 ========== //

std::unique_ptr<viml::DebuggerCLI> create_debugger_cli(std::shared_ptr<viml::VM> vm) {
    auto debugger = std::make_shared<viml::Debugger>(vm);
    auto debug_info = std::make_shared<viml::DebugInfo>();

    // 创建CLI调试器并设置调试器和调试信息
    auto cli = std::make_unique<DebuggerCLI>(vm, debugger, debug_info);

    return cli;
}

} // namespace viml